/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * GUI.java
 *
 * Created on Apr 9, 2009, 11:30:53 PM
 */

package system.ui;

import java.util.TimerTask;
import java.util.Timer;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

/**
 *
 * @author David
 */
public class Gui extends javax.swing.JFrame {

    private Engine engine;
    private JLabel[] blockDirections;
    private JLabel[] blockSpeeds;
    private JLabel[] blockReservations;
    private JLabel[] switches;
    private JCheckBox[] sensors;
    private Timer clearCheckBoxesTimer;

    /** Creates new form GUI */
    public Gui(Engine anEngine) {
        engine = anEngine;
        initComponents();
        loadArrays();
        clearCheckBoxesTimer = new Timer("Clear Sensors");
        setVisible(true);
    }

    private void loadArrays()
    {
        blockDirections = new JLabel[10];
        blockSpeeds = new JLabel[10];
        blockReservations = new JLabel[10];

        blockDirections[1] = blockDirection1;
        blockDirections[2] = blockDirection2;
        blockDirections[3] = blockDirection3;
        blockDirections[4] = blockDirection4;
        blockDirections[5] = blockDirection5;
        blockDirections[6] = blockDirection6;
        blockDirections[7] = blockDirection7;
        blockDirections[8] = blockDirection8;
        blockDirections[9] = blockDirection9;

        blockSpeeds[1] = blockSpeed1;
        blockSpeeds[2] = blockSpeed2;
        blockSpeeds[3] = blockSpeed3;
        blockSpeeds[4] = blockSpeed4;
        blockSpeeds[5] = blockSpeed5;
        blockSpeeds[6] = blockSpeed6;
        blockSpeeds[7] = blockSpeed7;
        blockSpeeds[8] = blockSpeed8;
        blockSpeeds[9] = blockSpeed9;

        blockReservations[1] = blockReserved1;
        blockReservations[2] = blockReserved2;
        blockReservations[3] = blockReserved3;
        blockReservations[4] = blockReserved4;
        blockReservations[5] = blockReserved5;
        blockReservations[6] = blockReserved6;
        blockReservations[7] = blockReserved7;
        blockReservations[8] = blockReserved8;
        blockReservations[9] = blockReserved9;

        switches = new JLabel[7];

        //Yes I know they don't look like the match,
        //Trust me, I messed up during the design part
        //and it was just easier not to fight it.
        //This matches up to what's on the GUI.
        switches[1] = switchState1;
        switches[2] = switchState3;
        switches[3] = switchState4;
        switches[4] = switchState5;
        switches[5] = switchState6;
        switches[6] = switchState2;

        sensors = new JCheckBox[16];

        sensors[1] = sensorTripped1;
        sensors[2] = sensorTripped2;
        sensors[3] = sensorTripped3;
        sensors[4] = sensorTripped4;
        sensors[5] = sensorTripped5;
        sensors[6] = sensorTripped6;
        sensors[7] = sensorTripped7;
        sensors[8] = sensorTripped8;
        sensors[9] = sensorTripped9;
        sensors[10] = sensorTripped10;
        sensors[11] = sensorTripped11;
        sensors[12] = sensorTripped12;
        sensors[13] = sensorTripped13;
        sensors[14] = sensorTripped14;
        sensors[15] = sensorTripped15;
    }

    /**
     * Displays a warning box asking the user to reset the trains.
     */
    public void confirmReset()
    {
        JOptionPane.showMessageDialog(this,
                "Please reset the train server and reposition " +
                    "trains.",
                "Reset Required",
                JOptionPane.WARNING_MESSAGE);
    }

     /**
     * Appends a string to the text in the messages box
     * in the GUI.
     *
     * Appends a line break.
     * @param string
     */
    public void mAreaPrintln(String string)
    {
        String text = messageTextArea.getText() + string + "\n";
        messageTextArea.setText(text);
    }

    /**
     * Updates the train's label showing direction.
     * @param id specifies to update train 1 or 2.
     * @param direction the direction to update to.
     */
    public void updateTrainDirection(int id, String direction)
    {
        switch (id)
        {
            case 1:
                directionDisplay1.setText(direction);
                break;
            case 2:
                directionDisplay2.setText(direction);
                break;
            default:
        }
    }

    /**
     * Updates the blocks controlled by a train.
     * @param id train ID to control a block.
     * @param controlStr what to update the string to.
     */
    public void updateBlocksControlled(int id, String controlStr)
    {
        switch(id)
        {
            case 1:
                controlDisplay1.setText(controlStr);
                break;
            case 2:
                controlDisplay2.setText(controlStr);
                break;
            default:
        }
    }

    /**
     * Updates the hand controller's status label.
     *
     * @param id the id of the hand controller
     * @param status what to update to.
     */
    public void updateHandController(int id, String status)
    {
        switch(id)
        {
            case 1:
                handControllerStatus1.setText(status);
                break;
            case 2:
                handControllerStatus2.setText(status);
                break;
            default:
        }
    }

    /**
     * Updates the mode selected.
     *
     * This is intended to be called when the engine
     * first recieves the gui reference and is syncing initially.
     *
     * @param mode a char, either a, b, or c describing the mode to
     * select.
     */
    public void updateModeSelection(char mode)
    {
        switch(mode)
        {
            case 'c':
                cRadioButton.setSelected(true);
                break;
            case 'b':
                bRadioButton.setSelected(true);
                break;
            case 'a':
                bRadioButton.setSelected(true);
                break;
        }
    }

    /**
     * Retrieves the speed as shown in the gui of a train.
     *
     * @param id the id of the train to be retrieved.
     * @return the speed of the train
     */
    public int getTrainSpeed(int id)
    {
        switch(id)
        {
            case 1:
                return (Integer)speedSpinner1.getValue();
            case 2:
                return (Integer)speedSpinner2.getValue();
            default:
                return 0;
        }
    }

    /**
     * Resets a trains status fields to blanks.
     * @param id id of the train to wipe.
     */
    public void wipeTrainStatus(int id)
    {
        switch(id)
        {
            case 1:
                controlDisplay1.setText("");
                directionDisplay1.setText("");
                handControllerStatus1.setText("");
                break;
            case 2:
                controlDisplay2.setText("");
                directionDisplay2.setText("");
                handControllerStatus2.setText("");
                break;
            default:
        }
    }

    /**
     * Updates the values of a particular block's reserved status.
     * @param id id of the block to update.
     * @param reserved the new value
     */
    public void updateBlockReserved(int id, String reserved)
    {
        blockReservations[id].setText(reserved);
    }

    /**
     * Updates the values of a particular block's direction.
     * @param id id of the block to update.
     * @param direction the new value
     */
    public void updateBlockDirection(int id, String direction)
    {
        blockDirections[id].setText(direction);
    }

    /**
     * Updates the values of a particular block's direction.
     * @param id id of the block to update.
     * @param direction the new value
     */
    public void updateBlockSpeed(int id, String speed)
    {
        blockSpeeds[id].setText(speed);
    }

    /**
     * Updates a switch's status.
     * @param id id of the switch to update
     * @param angle the new value
     */
    public void updateSwitch(int id, String angle)
    {
        switches[id].setText(angle);
    }

    /**
     * Updates a sensor's status.
     *
     * If the sensor is tripped, this method also sets
     * up a TimerTask to clear the box after 5 seconds.
     * @param id the id of the sensor to update
     * @param tripped <code>true</code> to flag the sensor as tripped
     * <code>false</code> to clear the sensor's status.
     */
    public void updateSensor(int id, boolean tripped)
    {
        sensors[id].setSelected(tripped);
        if (tripped)
        {
            clearCheckBoxesTimer.schedule(new ClearSensorsTask(id), 5000);
        }
    }


    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        operationModes = new javax.swing.ButtonGroup();
        runTrainButton = new javax.swing.JToggleButton();
        cRadioButton = new javax.swing.JRadioButton();
        bRadioButton = new javax.swing.JRadioButton();
        aRadioButton = new javax.swing.JRadioButton();
        messageScrollPane = new javax.swing.JScrollPane();
        messageTextArea = new javax.swing.JTextArea();
        javax.swing.JLabel messageLabel = new javax.swing.JLabel();
        javax.swing.JPanel train1Panel = new javax.swing.JPanel();
        javax.swing.JLabel train1Label = new javax.swing.JLabel();
        javax.swing.JLabel controlLabel = new javax.swing.JLabel();
        controlDisplay1 = new javax.swing.JLabel();
        javax.swing.JLabel speedLabel1 = new javax.swing.JLabel();
        speedSpinner1 = new javax.swing.JSpinner();
        javax.swing.JLabel directionLabel1 = new javax.swing.JLabel();
        directionDisplay1 = new javax.swing.JLabel();
        javax.swing.JLabel handControllerLabel1 = new javax.swing.JLabel();
        handControllerStatus1 = new javax.swing.JLabel();
        javax.swing.JPanel train2Panel = new javax.swing.JPanel();
        javax.swing.JLabel train2Label = new javax.swing.JLabel();
        javax.swing.JLabel controlLabel2 = new javax.swing.JLabel();
        controlDisplay2 = new javax.swing.JLabel();
        javax.swing.JLabel speedLabel2 = new javax.swing.JLabel();
        speedSpinner2 = new javax.swing.JSpinner();
        javax.swing.JLabel directionLabel2 = new javax.swing.JLabel();
        directionDisplay2 = new javax.swing.JLabel();
        javax.swing.JLabel handControllerLabel2 = new javax.swing.JLabel();
        handControllerStatus2 = new javax.swing.JLabel();
        javax.swing.JPanel blockPanel = new javax.swing.JPanel();
        javax.swing.JLabel blockStatusAreaLabel = new javax.swing.JLabel();
        javax.swing.JPanel specBlockPanel1 = new javax.swing.JPanel();
        javax.swing.JLabel blockLabel = new javax.swing.JLabel();
        javax.swing.JLabel reservedLabel = new javax.swing.JLabel();
        javax.swing.JLabel directionLabel = new javax.swing.JLabel();
        blockSpeedLabel = new javax.swing.JLabel();
        blockSpeed1 = new javax.swing.JLabel();
        blockDirection1 = new javax.swing.JLabel();
        blockReserved1 = new javax.swing.JLabel();
        javax.swing.JPanel specBlockPanel2 = new javax.swing.JPanel();
        javax.swing.JLabel blockLabel1 = new javax.swing.JLabel();
        javax.swing.JLabel reservedLabel1 = new javax.swing.JLabel();
        javax.swing.JLabel directionLabel3 = new javax.swing.JLabel();
        blockSpeedLabel1 = new javax.swing.JLabel();
        blockSpeed2 = new javax.swing.JLabel();
        blockDirection2 = new javax.swing.JLabel();
        blockReserved2 = new javax.swing.JLabel();
        javax.swing.JPanel specBlockPanel3 = new javax.swing.JPanel();
        javax.swing.JLabel blockLabel2 = new javax.swing.JLabel();
        javax.swing.JLabel reservedLabel2 = new javax.swing.JLabel();
        javax.swing.JLabel directionLabel4 = new javax.swing.JLabel();
        blockSpeedLabel2 = new javax.swing.JLabel();
        blockSpeed3 = new javax.swing.JLabel();
        blockDirection3 = new javax.swing.JLabel();
        blockReserved3 = new javax.swing.JLabel();
        javax.swing.JPanel specBlockPanel7 = new javax.swing.JPanel();
        javax.swing.JLabel blockLabel6 = new javax.swing.JLabel();
        javax.swing.JLabel reservedLabel6 = new javax.swing.JLabel();
        javax.swing.JLabel directionLabel8 = new javax.swing.JLabel();
        blockSpeedLabel6 = new javax.swing.JLabel();
        blockSpeed7 = new javax.swing.JLabel();
        blockDirection7 = new javax.swing.JLabel();
        blockReserved7 = new javax.swing.JLabel();
        javax.swing.JPanel specBlockPanel8 = new javax.swing.JPanel();
        javax.swing.JLabel blockLabel7 = new javax.swing.JLabel();
        javax.swing.JLabel reservedLabel7 = new javax.swing.JLabel();
        javax.swing.JLabel directionLabel9 = new javax.swing.JLabel();
        blockSpeedLabel7 = new javax.swing.JLabel();
        blockSpeed8 = new javax.swing.JLabel();
        blockDirection8 = new javax.swing.JLabel();
        blockReserved8 = new javax.swing.JLabel();
        javax.swing.JPanel specBlockPanel9 = new javax.swing.JPanel();
        javax.swing.JLabel blockLabel8 = new javax.swing.JLabel();
        javax.swing.JLabel reservedLabel8 = new javax.swing.JLabel();
        javax.swing.JLabel directionLabel10 = new javax.swing.JLabel();
        blockSpeedLabel8 = new javax.swing.JLabel();
        blockSpeed9 = new javax.swing.JLabel();
        blockDirection9 = new javax.swing.JLabel();
        blockReserved9 = new javax.swing.JLabel();
        javax.swing.JPanel specBlockPanel6 = new javax.swing.JPanel();
        javax.swing.JLabel blockLabel5 = new javax.swing.JLabel();
        javax.swing.JLabel reservedLabel5 = new javax.swing.JLabel();
        javax.swing.JLabel directionLabel7 = new javax.swing.JLabel();
        blockSpeedLabel5 = new javax.swing.JLabel();
        blockSpeed6 = new javax.swing.JLabel();
        blockDirection6 = new javax.swing.JLabel();
        blockReserved6 = new javax.swing.JLabel();
        javax.swing.JPanel specBlockPanel5 = new javax.swing.JPanel();
        javax.swing.JLabel blockLabel4 = new javax.swing.JLabel();
        javax.swing.JLabel reservedLabel4 = new javax.swing.JLabel();
        javax.swing.JLabel directionLabel6 = new javax.swing.JLabel();
        blockSpeedLabel4 = new javax.swing.JLabel();
        blockSpeed5 = new javax.swing.JLabel();
        blockDirection5 = new javax.swing.JLabel();
        blockReserved5 = new javax.swing.JLabel();
        javax.swing.JPanel specBlockPanel4 = new javax.swing.JPanel();
        javax.swing.JLabel blockLabel3 = new javax.swing.JLabel();
        javax.swing.JLabel reservedLabel3 = new javax.swing.JLabel();
        javax.swing.JLabel directionLabel5 = new javax.swing.JLabel();
        blockSpeedLabel3 = new javax.swing.JLabel();
        blockSpeed4 = new javax.swing.JLabel();
        blockDirection4 = new javax.swing.JLabel();
        blockReserved4 = new javax.swing.JLabel();
        javax.swing.JPanel switchAreaPanel = new javax.swing.JPanel();
        javax.swing.JLabel switchAreaLabel = new javax.swing.JLabel();
        javax.swing.JPanel specSwitchPanel = new javax.swing.JPanel();
        javax.swing.JLabel switchLabel = new javax.swing.JLabel();
        switchState1 = new javax.swing.JLabel();
        javax.swing.JLabel specSwitchLabel = new javax.swing.JLabel();
        javax.swing.JPanel specSwitchPanel2 = new javax.swing.JPanel();
        javax.swing.JLabel switchLabel2 = new javax.swing.JLabel();
        switchState3 = new javax.swing.JLabel();
        javax.swing.JLabel specSwitchLabel2 = new javax.swing.JLabel();
        javax.swing.JPanel specSwitchPanel3 = new javax.swing.JPanel();
        javax.swing.JLabel switchLabel3 = new javax.swing.JLabel();
        switchState4 = new javax.swing.JLabel();
        javax.swing.JLabel specSwitchLabel3 = new javax.swing.JLabel();
        javax.swing.JPanel specSwitchPanel4 = new javax.swing.JPanel();
        javax.swing.JLabel switchLabel4 = new javax.swing.JLabel();
        switchState5 = new javax.swing.JLabel();
        javax.swing.JLabel specSwitchLabel4 = new javax.swing.JLabel();
        javax.swing.JPanel specSwitchPanel5 = new javax.swing.JPanel();
        javax.swing.JLabel switchLabel5 = new javax.swing.JLabel();
        switchState6 = new javax.swing.JLabel();
        javax.swing.JLabel specSwitchLabel5 = new javax.swing.JLabel();
        javax.swing.JPanel specSwitchPanel1 = new javax.swing.JPanel();
        javax.swing.JLabel switchLabel1 = new javax.swing.JLabel();
        switchState2 = new javax.swing.JLabel();
        javax.swing.JLabel specSwitchLabel1 = new javax.swing.JLabel();
        javax.swing.JPanel sensorAreaPanel = new javax.swing.JPanel();
        javax.swing.JLabel Sensors = new javax.swing.JLabel();
        sensorTripped1 = new javax.swing.JCheckBox();
        sensorTripped2 = new javax.swing.JCheckBox();
        sensorTripped3 = new javax.swing.JCheckBox();
        sensorTripped4 = new javax.swing.JCheckBox();
        sensorTripped5 = new javax.swing.JCheckBox();
        sensorTripped6 = new javax.swing.JCheckBox();
        sensorTripped7 = new javax.swing.JCheckBox();
        sensorTripped8 = new javax.swing.JCheckBox();
        sensorTripped9 = new javax.swing.JCheckBox();
        sensorTripped10 = new javax.swing.JCheckBox();
        sensorTripped11 = new javax.swing.JCheckBox();
        sensorTripped12 = new javax.swing.JCheckBox();
        sensorTripped13 = new javax.swing.JCheckBox();
        sensorTripped14 = new javax.swing.JCheckBox();
        sensorTripped15 = new javax.swing.JCheckBox();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("Train Client");
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        runTrainButton.setText("Run Train(s)");
        runTrainButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                runTrainsToggle(evt);
            }
        });

        operationModes.add(cRadioButton);
        cRadioButton.setSelected(true);
        cRadioButton.setText("C Requirements");
        cRadioButton.setToolTipText("Run one train on a prespecified route.");
        cRadioButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                setUpCRequirements(evt);
            }
        });

        operationModes.add(bRadioButton);
        bRadioButton.setText("B Requirements");
        bRadioButton.setToolTipText("Allow one train operated via the hand control.");
        bRadioButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bRadioButtonActionPerformed(evt);
            }
        });

        operationModes.add(aRadioButton);
        aRadioButton.setText("A Requirements");
        aRadioButton.setToolTipText("Two trains: one operated by the program and the other operated by the hand controller.");

        messageTextArea.setColumns(20);
        messageTextArea.setEditable(false);
        messageTextArea.setLineWrap(true);
        messageTextArea.setRows(5);
        messageTextArea.setToolTipText("Displays messages sent and recieved in plain english.");
        messageScrollPane.setViewportView(messageTextArea);

        messageLabel.setLabelFor(messageTextArea);
        messageLabel.setText("Messages");

        train1Panel.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        train1Label.setText("Train 1");

        controlLabel.setText("Controls Blocks:");

        speedLabel1.setText("Speed: ");

        speedSpinner1.setModel(new javax.swing.SpinnerNumberModel(4, 0, 7, 1));
        speedSpinner1.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                speedSpinner1StateChanged(evt);
            }
        });

        directionLabel1.setText("Direction: ");

        handControllerLabel1.setText("Hand Controller: ");

        javax.swing.GroupLayout train1PanelLayout = new javax.swing.GroupLayout(train1Panel);
        train1Panel.setLayout(train1PanelLayout);
        train1PanelLayout.setHorizontalGroup(
            train1PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(train1PanelLayout.createSequentialGroup()
                .addGroup(train1PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(train1Label)
                    .addGroup(train1PanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(controlLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(controlDisplay1, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(train1PanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(directionLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(directionDisplay1, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(train1PanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(speedLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(speedSpinner1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(train1PanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(handControllerLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(handControllerStatus1)))
                .addContainerGap(74, Short.MAX_VALUE))
        );
        train1PanelLayout.setVerticalGroup(
            train1PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(train1PanelLayout.createSequentialGroup()
                .addComponent(train1Label)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(train1PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(controlLabel)
                    .addComponent(controlDisplay1, javax.swing.GroupLayout.PREFERRED_SIZE, 15, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(train1PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(directionLabel1)
                    .addComponent(directionDisplay1, javax.swing.GroupLayout.PREFERRED_SIZE, 15, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(train1PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(speedLabel1)
                    .addComponent(speedSpinner1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(train1PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(handControllerLabel1)
                    .addComponent(handControllerStatus1))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        train2Panel.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        train2Label.setText("Train 2");

        controlLabel2.setText("Controls Blocks:");

        speedLabel2.setText("Speed: ");

        speedSpinner2.setModel(new javax.swing.SpinnerNumberModel(4, 0, 7, 1));
        speedSpinner2.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                speedSpinner2StateChanged(evt);
            }
        });

        directionLabel2.setText("Direction: ");

        handControllerLabel2.setText("Hand Controller: ");

        javax.swing.GroupLayout train2PanelLayout = new javax.swing.GroupLayout(train2Panel);
        train2Panel.setLayout(train2PanelLayout);
        train2PanelLayout.setHorizontalGroup(
            train2PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(train2PanelLayout.createSequentialGroup()
                .addGroup(train2PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(train2Label)
                    .addGroup(train2PanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(controlLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(controlDisplay2, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(train2PanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(directionLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(directionDisplay2, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(train2PanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(speedLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(speedSpinner2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(train2PanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(handControllerLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(handControllerStatus2)))
                .addContainerGap(82, Short.MAX_VALUE))
        );
        train2PanelLayout.setVerticalGroup(
            train2PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(train2PanelLayout.createSequentialGroup()
                .addComponent(train2Label)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(train2PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(controlLabel2)
                    .addComponent(controlDisplay2, javax.swing.GroupLayout.PREFERRED_SIZE, 15, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(train2PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(directionLabel2)
                    .addComponent(directionDisplay2, javax.swing.GroupLayout.PREFERRED_SIZE, 15, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(train2PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(speedLabel2)
                    .addComponent(speedSpinner2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(train2PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(handControllerLabel2)
                    .addComponent(handControllerStatus2))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        blockPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        blockStatusAreaLabel.setText("Block Status");

        specBlockPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        blockLabel.setText("Block 1");

        reservedLabel.setText("Reserved:");

        directionLabel.setText("Direction:");

        blockSpeedLabel.setText("Speed:");

        blockDirection1.setToolTipText("");

        javax.swing.GroupLayout specBlockPanel1Layout = new javax.swing.GroupLayout(specBlockPanel1);
        specBlockPanel1.setLayout(specBlockPanel1Layout);
        specBlockPanel1Layout.setHorizontalGroup(
            specBlockPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specBlockPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(specBlockPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(blockLabel)
                    .addGroup(specBlockPanel1Layout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addGroup(specBlockPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(reservedLabel)
                            .addComponent(directionLabel)
                            .addComponent(blockSpeedLabel))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(specBlockPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(blockSpeed1)
                            .addComponent(blockDirection1)
                            .addComponent(blockReserved1))))
                .addContainerGap(48, Short.MAX_VALUE))
        );
        specBlockPanel1Layout.setVerticalGroup(
            specBlockPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specBlockPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(blockLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(reservedLabel)
                    .addComponent(blockReserved1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(directionLabel)
                    .addComponent(blockDirection1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(blockSpeedLabel)
                    .addComponent(blockSpeed1))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        specBlockPanel2.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        blockLabel1.setText("Block 2");

        reservedLabel1.setText("Reserved:");

        directionLabel3.setText("Direction:");

        blockSpeedLabel1.setText("Speed:");

        blockDirection2.setToolTipText("");

        javax.swing.GroupLayout specBlockPanel2Layout = new javax.swing.GroupLayout(specBlockPanel2);
        specBlockPanel2.setLayout(specBlockPanel2Layout);
        specBlockPanel2Layout.setHorizontalGroup(
            specBlockPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specBlockPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(specBlockPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(blockLabel1)
                    .addGroup(specBlockPanel2Layout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addGroup(specBlockPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(reservedLabel1)
                            .addComponent(directionLabel3)
                            .addComponent(blockSpeedLabel1))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(specBlockPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(blockSpeed2)
                            .addComponent(blockDirection2)
                            .addComponent(blockReserved2))))
                .addContainerGap(41, Short.MAX_VALUE))
        );
        specBlockPanel2Layout.setVerticalGroup(
            specBlockPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specBlockPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(blockLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(reservedLabel1)
                    .addComponent(blockReserved2))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(directionLabel3)
                    .addComponent(blockDirection2))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(blockSpeedLabel1)
                    .addComponent(blockSpeed2))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        specBlockPanel3.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        blockLabel2.setText("Block 3");

        reservedLabel2.setText("Reserved:");

        directionLabel4.setText("Direction:");

        blockSpeedLabel2.setText("Speed:");

        blockDirection3.setToolTipText("");

        javax.swing.GroupLayout specBlockPanel3Layout = new javax.swing.GroupLayout(specBlockPanel3);
        specBlockPanel3.setLayout(specBlockPanel3Layout);
        specBlockPanel3Layout.setHorizontalGroup(
            specBlockPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specBlockPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(specBlockPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(blockLabel2)
                    .addGroup(specBlockPanel3Layout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addGroup(specBlockPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(reservedLabel2)
                            .addComponent(directionLabel4)
                            .addComponent(blockSpeedLabel2))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(specBlockPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(blockSpeed3)
                            .addComponent(blockDirection3)
                            .addComponent(blockReserved3))))
                .addContainerGap(51, Short.MAX_VALUE))
        );
        specBlockPanel3Layout.setVerticalGroup(
            specBlockPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specBlockPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(blockLabel2)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(reservedLabel2)
                    .addComponent(blockReserved3))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(directionLabel4)
                    .addComponent(blockDirection3))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(blockSpeedLabel2)
                    .addComponent(blockSpeed3))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        specBlockPanel7.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        blockLabel6.setText("Block 7");

        reservedLabel6.setText("Reserved:");

        directionLabel8.setText("Direction:");

        blockSpeedLabel6.setText("Speed:");

        blockDirection7.setToolTipText("");

        javax.swing.GroupLayout specBlockPanel7Layout = new javax.swing.GroupLayout(specBlockPanel7);
        specBlockPanel7.setLayout(specBlockPanel7Layout);
        specBlockPanel7Layout.setHorizontalGroup(
            specBlockPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specBlockPanel7Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(specBlockPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(blockLabel6)
                    .addGroup(specBlockPanel7Layout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addGroup(specBlockPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(reservedLabel6)
                            .addComponent(directionLabel8)
                            .addComponent(blockSpeedLabel6))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(specBlockPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(blockSpeed7)
                            .addComponent(blockDirection7)
                            .addComponent(blockReserved7))))
                .addContainerGap(48, Short.MAX_VALUE))
        );
        specBlockPanel7Layout.setVerticalGroup(
            specBlockPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specBlockPanel7Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(blockLabel6)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(reservedLabel6)
                    .addComponent(blockReserved7))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(directionLabel8)
                    .addComponent(blockDirection7))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(blockSpeedLabel6)
                    .addComponent(blockSpeed7))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        specBlockPanel8.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        blockLabel7.setText("Block 8");

        reservedLabel7.setText("Reserved:");

        directionLabel9.setText("Direction:");

        blockSpeedLabel7.setText("Speed:");

        blockDirection8.setToolTipText("");

        javax.swing.GroupLayout specBlockPanel8Layout = new javax.swing.GroupLayout(specBlockPanel8);
        specBlockPanel8.setLayout(specBlockPanel8Layout);
        specBlockPanel8Layout.setHorizontalGroup(
            specBlockPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specBlockPanel8Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(specBlockPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(blockLabel7)
                    .addGroup(specBlockPanel8Layout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addGroup(specBlockPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(reservedLabel7)
                            .addComponent(directionLabel9)
                            .addComponent(blockSpeedLabel7))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(specBlockPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(blockSpeed8)
                            .addComponent(blockDirection8)
                            .addComponent(blockReserved8))))
                .addContainerGap(41, Short.MAX_VALUE))
        );
        specBlockPanel8Layout.setVerticalGroup(
            specBlockPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specBlockPanel8Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(blockLabel7)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(reservedLabel7)
                    .addComponent(blockReserved8))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(directionLabel9)
                    .addComponent(blockDirection8))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(blockSpeedLabel7)
                    .addComponent(blockSpeed8))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        specBlockPanel9.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        blockLabel8.setText("Block 9");

        reservedLabel8.setText("Reserved:");

        directionLabel10.setText("Direction:");

        blockSpeedLabel8.setText("Speed:");

        blockDirection9.setToolTipText("");

        javax.swing.GroupLayout specBlockPanel9Layout = new javax.swing.GroupLayout(specBlockPanel9);
        specBlockPanel9.setLayout(specBlockPanel9Layout);
        specBlockPanel9Layout.setHorizontalGroup(
            specBlockPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specBlockPanel9Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(specBlockPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(blockLabel8)
                    .addGroup(specBlockPanel9Layout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addGroup(specBlockPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(reservedLabel8)
                            .addComponent(directionLabel10)
                            .addComponent(blockSpeedLabel8))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(specBlockPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(blockSpeed9)
                            .addComponent(blockDirection9)
                            .addComponent(blockReserved9))))
                .addContainerGap(51, Short.MAX_VALUE))
        );
        specBlockPanel9Layout.setVerticalGroup(
            specBlockPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specBlockPanel9Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(blockLabel8)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(reservedLabel8)
                    .addComponent(blockReserved9))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(directionLabel10)
                    .addComponent(blockDirection9))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(blockSpeedLabel8)
                    .addComponent(blockSpeed9))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        specBlockPanel6.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        blockLabel5.setText("Block 6");

        reservedLabel5.setText("Reserved:");

        directionLabel7.setText("Direction:");

        blockSpeedLabel5.setText("Speed:");

        blockDirection6.setToolTipText("");

        javax.swing.GroupLayout specBlockPanel6Layout = new javax.swing.GroupLayout(specBlockPanel6);
        specBlockPanel6.setLayout(specBlockPanel6Layout);
        specBlockPanel6Layout.setHorizontalGroup(
            specBlockPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specBlockPanel6Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(specBlockPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(blockLabel5)
                    .addGroup(specBlockPanel6Layout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addGroup(specBlockPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(reservedLabel5)
                            .addComponent(directionLabel7)
                            .addComponent(blockSpeedLabel5))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(specBlockPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(blockSpeed6)
                            .addComponent(blockDirection6)
                            .addComponent(blockReserved6))))
                .addContainerGap(51, Short.MAX_VALUE))
        );
        specBlockPanel6Layout.setVerticalGroup(
            specBlockPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specBlockPanel6Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(blockLabel5)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(reservedLabel5)
                    .addComponent(blockReserved6))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(directionLabel7)
                    .addComponent(blockDirection6))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(blockSpeedLabel5)
                    .addComponent(blockSpeed6))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        specBlockPanel5.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        blockLabel4.setText("Block 5");

        reservedLabel4.setText("Reserved:");

        directionLabel6.setText("Direction:");

        blockSpeedLabel4.setText("Speed:");

        blockDirection5.setToolTipText("");

        javax.swing.GroupLayout specBlockPanel5Layout = new javax.swing.GroupLayout(specBlockPanel5);
        specBlockPanel5.setLayout(specBlockPanel5Layout);
        specBlockPanel5Layout.setHorizontalGroup(
            specBlockPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specBlockPanel5Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(specBlockPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(blockLabel4)
                    .addGroup(specBlockPanel5Layout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addGroup(specBlockPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(reservedLabel4)
                            .addComponent(directionLabel6)
                            .addComponent(blockSpeedLabel4))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(specBlockPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(blockSpeed5)
                            .addComponent(blockDirection5)
                            .addComponent(blockReserved5))))
                .addContainerGap(41, Short.MAX_VALUE))
        );
        specBlockPanel5Layout.setVerticalGroup(
            specBlockPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specBlockPanel5Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(blockLabel4)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(reservedLabel4)
                    .addComponent(blockReserved5))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(directionLabel6)
                    .addComponent(blockDirection5))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(blockSpeedLabel4)
                    .addComponent(blockSpeed5))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        specBlockPanel4.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        blockLabel3.setText("Block 4");

        reservedLabel3.setText("Reserved:");

        directionLabel5.setText("Direction:");

        blockSpeedLabel3.setText("Speed:");

        blockDirection4.setToolTipText("");

        javax.swing.GroupLayout specBlockPanel4Layout = new javax.swing.GroupLayout(specBlockPanel4);
        specBlockPanel4.setLayout(specBlockPanel4Layout);
        specBlockPanel4Layout.setHorizontalGroup(
            specBlockPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specBlockPanel4Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(specBlockPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(blockLabel3)
                    .addGroup(specBlockPanel4Layout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addGroup(specBlockPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(reservedLabel3)
                            .addComponent(directionLabel5)
                            .addComponent(blockSpeedLabel3))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(specBlockPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(blockSpeed4)
                            .addComponent(blockDirection4)
                            .addComponent(blockReserved4))))
                .addContainerGap(48, Short.MAX_VALUE))
        );
        specBlockPanel4Layout.setVerticalGroup(
            specBlockPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specBlockPanel4Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(blockLabel3)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(reservedLabel3)
                    .addComponent(blockReserved4))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(directionLabel5)
                    .addComponent(blockDirection4))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specBlockPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(blockSpeedLabel3)
                    .addComponent(blockSpeed4))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout blockPanelLayout = new javax.swing.GroupLayout(blockPanel);
        blockPanel.setLayout(blockPanelLayout);
        blockPanelLayout.setHorizontalGroup(
            blockPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(blockPanelLayout.createSequentialGroup()
                .addGroup(blockPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(blockStatusAreaLabel)
                    .addGroup(blockPanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(blockPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(specBlockPanel4, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(specBlockPanel7, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(specBlockPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(blockPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(specBlockPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(specBlockPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(specBlockPanel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(blockPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(specBlockPanel6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(specBlockPanel9, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(specBlockPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
                .addContainerGap())
        );
        blockPanelLayout.setVerticalGroup(
            blockPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(blockPanelLayout.createSequentialGroup()
                .addComponent(blockStatusAreaLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(blockPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(specBlockPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(specBlockPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(specBlockPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(blockPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, blockPanelLayout.createSequentialGroup()
                        .addComponent(specBlockPanel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(specBlockPanel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(blockPanelLayout.createSequentialGroup()
                        .addComponent(specBlockPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(specBlockPanel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(blockPanelLayout.createSequentialGroup()
                        .addComponent(specBlockPanel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(specBlockPanel9, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addGap(117, 117, 117))
        );

        switchAreaPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        switchAreaLabel.setText("Switches");

        specSwitchPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        switchLabel.setText("State: ");

        switchState1.setText("180");

        specSwitchLabel.setText("Switch 1");

        javax.swing.GroupLayout specSwitchPanelLayout = new javax.swing.GroupLayout(specSwitchPanel);
        specSwitchPanel.setLayout(specSwitchPanelLayout);
        specSwitchPanelLayout.setHorizontalGroup(
            specSwitchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specSwitchPanelLayout.createSequentialGroup()
                .addGroup(specSwitchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(specSwitchPanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(switchLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(switchState1))
                    .addComponent(specSwitchLabel))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        specSwitchPanelLayout.setVerticalGroup(
            specSwitchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specSwitchPanelLayout.createSequentialGroup()
                .addComponent(specSwitchLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specSwitchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(switchLabel)
                    .addComponent(switchState1))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        specSwitchPanel2.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        switchLabel2.setText("State: ");

        switchState3.setText("180");

        specSwitchLabel2.setText("Switch 2");

        javax.swing.GroupLayout specSwitchPanel2Layout = new javax.swing.GroupLayout(specSwitchPanel2);
        specSwitchPanel2.setLayout(specSwitchPanel2Layout);
        specSwitchPanel2Layout.setHorizontalGroup(
            specSwitchPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specSwitchPanel2Layout.createSequentialGroup()
                .addGroup(specSwitchPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(specSwitchPanel2Layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(switchLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(switchState3))
                    .addComponent(specSwitchLabel2))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        specSwitchPanel2Layout.setVerticalGroup(
            specSwitchPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specSwitchPanel2Layout.createSequentialGroup()
                .addComponent(specSwitchLabel2)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specSwitchPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(switchLabel2)
                    .addComponent(switchState3))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        specSwitchPanel3.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        switchLabel3.setText("State: ");

        switchState4.setText("180");

        specSwitchLabel3.setText("Switch 3");

        javax.swing.GroupLayout specSwitchPanel3Layout = new javax.swing.GroupLayout(specSwitchPanel3);
        specSwitchPanel3.setLayout(specSwitchPanel3Layout);
        specSwitchPanel3Layout.setHorizontalGroup(
            specSwitchPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specSwitchPanel3Layout.createSequentialGroup()
                .addGroup(specSwitchPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(specSwitchPanel3Layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(switchLabel3)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(switchState4))
                    .addComponent(specSwitchLabel3))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        specSwitchPanel3Layout.setVerticalGroup(
            specSwitchPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specSwitchPanel3Layout.createSequentialGroup()
                .addComponent(specSwitchLabel3)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specSwitchPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(switchLabel3)
                    .addComponent(switchState4))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        specSwitchPanel4.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        switchLabel4.setText("State: ");

        switchState5.setText("180");

        specSwitchLabel4.setText("Switch 4");

        javax.swing.GroupLayout specSwitchPanel4Layout = new javax.swing.GroupLayout(specSwitchPanel4);
        specSwitchPanel4.setLayout(specSwitchPanel4Layout);
        specSwitchPanel4Layout.setHorizontalGroup(
            specSwitchPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specSwitchPanel4Layout.createSequentialGroup()
                .addGroup(specSwitchPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(specSwitchPanel4Layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(switchLabel4)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(switchState5))
                    .addComponent(specSwitchLabel4))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        specSwitchPanel4Layout.setVerticalGroup(
            specSwitchPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specSwitchPanel4Layout.createSequentialGroup()
                .addComponent(specSwitchLabel4)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specSwitchPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(switchLabel4)
                    .addComponent(switchState5))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        specSwitchPanel5.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        switchLabel5.setText("State: ");

        switchState6.setText("180");

        specSwitchLabel5.setText("Switch 5");

        javax.swing.GroupLayout specSwitchPanel5Layout = new javax.swing.GroupLayout(specSwitchPanel5);
        specSwitchPanel5.setLayout(specSwitchPanel5Layout);
        specSwitchPanel5Layout.setHorizontalGroup(
            specSwitchPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specSwitchPanel5Layout.createSequentialGroup()
                .addGroup(specSwitchPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(specSwitchPanel5Layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(switchLabel5)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(switchState6))
                    .addComponent(specSwitchLabel5))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        specSwitchPanel5Layout.setVerticalGroup(
            specSwitchPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specSwitchPanel5Layout.createSequentialGroup()
                .addComponent(specSwitchLabel5)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specSwitchPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(switchLabel5)
                    .addComponent(switchState6))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        specSwitchPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        switchLabel1.setText("State: ");

        switchState2.setText("180");

        specSwitchLabel1.setText("Switch 6");

        javax.swing.GroupLayout specSwitchPanel1Layout = new javax.swing.GroupLayout(specSwitchPanel1);
        specSwitchPanel1.setLayout(specSwitchPanel1Layout);
        specSwitchPanel1Layout.setHorizontalGroup(
            specSwitchPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specSwitchPanel1Layout.createSequentialGroup()
                .addGroup(specSwitchPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(specSwitchPanel1Layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(switchLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(switchState2))
                    .addComponent(specSwitchLabel1))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        specSwitchPanel1Layout.setVerticalGroup(
            specSwitchPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(specSwitchPanel1Layout.createSequentialGroup()
                .addComponent(specSwitchLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(specSwitchPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(switchLabel1)
                    .addComponent(switchState2))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout switchAreaPanelLayout = new javax.swing.GroupLayout(switchAreaPanel);
        switchAreaPanel.setLayout(switchAreaPanelLayout);
        switchAreaPanelLayout.setHorizontalGroup(
            switchAreaPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(switchAreaPanelLayout.createSequentialGroup()
                .addGroup(switchAreaPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(switchAreaLabel)
                    .addGroup(switchAreaPanelLayout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addComponent(specSwitchPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(specSwitchPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(switchAreaPanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(specSwitchPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(specSwitchPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(switchAreaPanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(specSwitchPanel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(specSwitchPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        switchAreaPanelLayout.setVerticalGroup(
            switchAreaPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(switchAreaPanelLayout.createSequentialGroup()
                .addComponent(switchAreaLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(switchAreaPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(specSwitchPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(specSwitchPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(switchAreaPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(specSwitchPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(specSwitchPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(switchAreaPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(specSwitchPanel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(specSwitchPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        sensorAreaPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        Sensors.setText("Sensors");

        sensorTripped1.setText("Sensor 1");
        sensorTripped1.setEnabled(false);

        sensorTripped2.setText("Sensor 2");
        sensorTripped2.setEnabled(false);

        sensorTripped3.setText("Sensor 3");
        sensorTripped3.setEnabled(false);

        sensorTripped4.setText("Sensor 4");
        sensorTripped4.setEnabled(false);

        sensorTripped5.setText("Sensor 5");
        sensorTripped5.setEnabled(false);

        sensorTripped6.setText("Sensor 6");
        sensorTripped6.setEnabled(false);

        sensorTripped7.setText("Sensor 7");
        sensorTripped7.setEnabled(false);

        sensorTripped8.setText("Sensor 8");
        sensorTripped8.setEnabled(false);

        sensorTripped9.setText("Sensor 9");
        sensorTripped9.setEnabled(false);

        sensorTripped10.setText("Sensor 10");
        sensorTripped10.setEnabled(false);

        sensorTripped11.setText("Sensor11");
        sensorTripped11.setEnabled(false);

        sensorTripped12.setText("Sensor 12");
        sensorTripped12.setEnabled(false);

        sensorTripped13.setText("Sensor 13");
        sensorTripped13.setEnabled(false);

        sensorTripped14.setText("Sensor 14");
        sensorTripped14.setEnabled(false);

        sensorTripped15.setText("Sensor 15");
        sensorTripped15.setEnabled(false);

        javax.swing.GroupLayout sensorAreaPanelLayout = new javax.swing.GroupLayout(sensorAreaPanel);
        sensorAreaPanel.setLayout(sensorAreaPanelLayout);
        sensorAreaPanelLayout.setHorizontalGroup(
            sensorAreaPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(sensorAreaPanelLayout.createSequentialGroup()
                .addGroup(sensorAreaPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(Sensors)
                    .addGroup(sensorAreaPanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(sensorAreaPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(sensorAreaPanelLayout.createSequentialGroup()
                                .addComponent(sensorTripped11)
                                .addGap(2, 2, 2))
                            .addComponent(sensorTripped13)
                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, sensorAreaPanelLayout.createSequentialGroup()
                                .addGroup(sensorAreaPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(sensorTripped9)
                                    .addComponent(sensorTripped5)
                                    .addComponent(sensorTripped3)
                                    .addComponent(sensorTripped1))
                                .addGap(6, 6, 6))
                            .addComponent(sensorTripped7)
                            .addComponent(sensorTripped15))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 30, Short.MAX_VALUE)
                        .addGroup(sensorAreaPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(sensorTripped12, javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(sensorTripped14, javax.swing.GroupLayout.Alignment.TRAILING)
                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, sensorAreaPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(sensorTripped2)
                                .addComponent(sensorTripped4)
                                .addComponent(sensorTripped6)
                                .addComponent(sensorTripped8)
                                .addComponent(sensorTripped10)))))
                .addContainerGap())
        );
        sensorAreaPanelLayout.setVerticalGroup(
            sensorAreaPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(sensorAreaPanelLayout.createSequentialGroup()
                .addComponent(Sensors)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(sensorAreaPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(sensorAreaPanelLayout.createSequentialGroup()
                        .addComponent(sensorTripped2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(sensorTripped4)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(sensorTripped6)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(sensorTripped8)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(sensorTripped10)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(sensorTripped12)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(sensorTripped14))
                    .addGroup(sensorAreaPanelLayout.createSequentialGroup()
                        .addComponent(sensorTripped1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(sensorTripped3)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(sensorTripped5)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(sensorTripped7)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(sensorTripped9)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(sensorTripped11)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(sensorTripped13)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(sensorTripped15)))
                .addContainerGap())
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(blockPanel, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(runTrainButton)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(cRadioButton)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(bRadioButton))
                            .addComponent(train1Panel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(train2Panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(aRadioButton))))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(sensorAreaPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(switchAreaPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(6, 6, 6)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(messageLabel)
                    .addComponent(messageScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 276, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(runTrainButton)
                    .addComponent(messageLabel))
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(cRadioButton)
                            .addComponent(bRadioButton)
                            .addComponent(aRadioButton))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(train2Panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                    .addComponent(train1Panel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(blockPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 412, Short.MAX_VALUE))
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(sensorAreaPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(switchAreaPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
                    .addGroup(layout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(messageScrollPane)))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void runTrainsToggle(java.awt.event.ActionEvent evt)//GEN-FIRST:event_runTrainsToggle
    {//GEN-HEADEREND:event_runTrainsToggle
        if(runTrainButton.isSelected())
        {
            engine.runTrains();
        }
        else
        {
            engine.stopTrains();
            confirmReset();
        }
    }//GEN-LAST:event_runTrainsToggle

    private void setUpCRequirements(java.awt.event.ActionEvent evt)//GEN-FIRST:event_setUpCRequirements
    {//GEN-HEADEREND:event_setUpCRequirements
        if (runTrainButton.isSelected())
        {
            runTrainButton.setSelected(false);
            engine.stopTrains();
            confirmReset();
        }
        if(cRadioButton.isSelected())
        {
            engine.setUpCRequirements();
        }
    }//GEN-LAST:event_setUpCRequirements

    private void speedSpinner1StateChanged(javax.swing.event.ChangeEvent evt)//GEN-FIRST:event_speedSpinner1StateChanged
    {//GEN-HEADEREND:event_speedSpinner1StateChanged
        int currentValue = (Integer)speedSpinner1.getValue();
        int newValue = engine.changeTrainSpeed(1, currentValue);
        speedSpinner1.setValue(newValue);
    }//GEN-LAST:event_speedSpinner1StateChanged

    private void speedSpinner2StateChanged(javax.swing.event.ChangeEvent evt)//GEN-FIRST:event_speedSpinner2StateChanged
    {//GEN-HEADEREND:event_speedSpinner2StateChanged
        int currentValue = (Integer)speedSpinner1.getValue();
        int newValue = engine.changeTrainSpeed(1, currentValue);
        speedSpinner1.setValue(newValue);
    }//GEN-LAST:event_speedSpinner2StateChanged

    private void formWindowClosing(java.awt.event.WindowEvent evt)//GEN-FIRST:event_formWindowClosing
    {//GEN-HEADEREND:event_formWindowClosing
        engine.shutdown();
        this.dispose();
    }//GEN-LAST:event_formWindowClosing

    private void bRadioButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_bRadioButtonActionPerformed
    {//GEN-HEADEREND:event_bRadioButtonActionPerformed
        if (runTrainButton.isSelected())
        {
            runTrainButton.setSelected(false);
            engine.stopTrains();
            confirmReset();
        }
        if(bRadioButton.isSelected())
        {
            engine.setUpBRequirements();
        }
    }//GEN-LAST:event_bRadioButtonActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JRadioButton aRadioButton;
    private javax.swing.JRadioButton bRadioButton;
    private javax.swing.JLabel blockDirection1;
    private javax.swing.JLabel blockDirection2;
    private javax.swing.JLabel blockDirection3;
    private javax.swing.JLabel blockDirection4;
    private javax.swing.JLabel blockDirection5;
    private javax.swing.JLabel blockDirection6;
    private javax.swing.JLabel blockDirection7;
    private javax.swing.JLabel blockDirection8;
    private javax.swing.JLabel blockDirection9;
    private javax.swing.JLabel blockReserved1;
    private javax.swing.JLabel blockReserved2;
    private javax.swing.JLabel blockReserved3;
    private javax.swing.JLabel blockReserved4;
    private javax.swing.JLabel blockReserved5;
    private javax.swing.JLabel blockReserved6;
    private javax.swing.JLabel blockReserved7;
    private javax.swing.JLabel blockReserved8;
    private javax.swing.JLabel blockReserved9;
    private javax.swing.JLabel blockSpeed1;
    private javax.swing.JLabel blockSpeed2;
    private javax.swing.JLabel blockSpeed3;
    private javax.swing.JLabel blockSpeed4;
    private javax.swing.JLabel blockSpeed5;
    private javax.swing.JLabel blockSpeed6;
    private javax.swing.JLabel blockSpeed7;
    private javax.swing.JLabel blockSpeed8;
    private javax.swing.JLabel blockSpeed9;
    private javax.swing.JLabel blockSpeedLabel;
    private javax.swing.JLabel blockSpeedLabel1;
    private javax.swing.JLabel blockSpeedLabel2;
    private javax.swing.JLabel blockSpeedLabel3;
    private javax.swing.JLabel blockSpeedLabel4;
    private javax.swing.JLabel blockSpeedLabel5;
    private javax.swing.JLabel blockSpeedLabel6;
    private javax.swing.JLabel blockSpeedLabel7;
    private javax.swing.JLabel blockSpeedLabel8;
    private javax.swing.JRadioButton cRadioButton;
    private javax.swing.JLabel controlDisplay1;
    private javax.swing.JLabel controlDisplay2;
    private javax.swing.JLabel directionDisplay1;
    private javax.swing.JLabel directionDisplay2;
    private javax.swing.JLabel handControllerStatus1;
    private javax.swing.JLabel handControllerStatus2;
    private javax.swing.JScrollPane messageScrollPane;
    private javax.swing.JTextArea messageTextArea;
    private javax.swing.ButtonGroup operationModes;
    private javax.swing.JToggleButton runTrainButton;
    private javax.swing.JCheckBox sensorTripped1;
    private javax.swing.JCheckBox sensorTripped10;
    private javax.swing.JCheckBox sensorTripped11;
    private javax.swing.JCheckBox sensorTripped12;
    private javax.swing.JCheckBox sensorTripped13;
    private javax.swing.JCheckBox sensorTripped14;
    private javax.swing.JCheckBox sensorTripped15;
    private javax.swing.JCheckBox sensorTripped2;
    private javax.swing.JCheckBox sensorTripped3;
    private javax.swing.JCheckBox sensorTripped4;
    private javax.swing.JCheckBox sensorTripped5;
    private javax.swing.JCheckBox sensorTripped6;
    private javax.swing.JCheckBox sensorTripped7;
    private javax.swing.JCheckBox sensorTripped8;
    private javax.swing.JCheckBox sensorTripped9;
    private javax.swing.JSpinner speedSpinner1;
    private javax.swing.JSpinner speedSpinner2;
    private javax.swing.JLabel switchState1;
    private javax.swing.JLabel switchState2;
    private javax.swing.JLabel switchState3;
    private javax.swing.JLabel switchState4;
    private javax.swing.JLabel switchState5;
    private javax.swing.JLabel switchState6;
    // End of variables declaration//GEN-END:variables

    private class ClearSensorsTask extends TimerTask
    {
        private int sensorID;

        private ClearSensorsTask(int id)
        {
            this.sensorID = id;
        }

        @Override
        public void run()
        {
            updateSensor(sensorID, false);
        }
    }
}